package org.bjf.modules.sys.web.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.google.common.collect.Lists;
import org.bjf.modules.core.web.core.PageVO;
import org.bjf.modules.sys.bean.AuthModuleBean;
import org.bjf.modules.sys.bean.SysRole;
import org.bjf.modules.sys.bean.SysRolePerm;
import org.bjf.modules.sys.enums.AuthMethod;
import org.bjf.modules.sys.annotation.AuthModule;
import org.bjf.modules.sys.query.SysRoleQuery;
import org.bjf.modules.sys.service.SysRoleMenuService;
import org.bjf.modules.sys.service.SysRolePermService;
import org.bjf.modules.sys.service.SysRoleService;
import org.bjf.modules.sys.web.vo.PermVO;
import org.bjf.runner.LiveBeanPostProcessor;
import org.bjf.security.satoken.SaTokenAdminUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("admin")
@AuthModule(code = "role", desc = "角色管理")
public class SysRoleController {

    @Autowired
    private SysRoleService roleService;
    @Autowired
    private SysRolePermService rolePermService;
    @Autowired
    private SysRoleMenuService roleMenuService;

    @RequestMapping("role/detail")
    public SysRole detail(@RequestParam long id) {
        return roleService.get(id);
    }

    @RequestMapping("role/list")
    public List<SysRole> list(SysRoleQuery query) {
        return roleService.list(query);
    }

    @RequestMapping("role/listPage")
    public PageVO<SysRole> listPage(SysRoleQuery query) {
        return roleService.listPage(query);
    }

    @RequestMapping("role/listAll")
    public List<SysRole> listAll(SysRoleQuery query) {
        return roleService.listAll(query);
    }


    @RequestMapping("role/add")
    @SaCheckPermission(value = "role-add", orRole = "super-admin", type = SaTokenAdminUtil.TYPE)
    public void add(@Validated SysRole role) {
        roleService.add(role);
    }

    @RequestMapping("role/update")
    @SaCheckPermission(value = "role-update", orRole = "super-admin", type = SaTokenAdminUtil.TYPE)
    public void update(@Validated SysRole role) {
        roleService.updateById(role);
    }

    @RequestMapping("role/delete")
    @SaCheckPermission(value = "role-delete", orRole = "super-admin", type = SaTokenAdminUtil.TYPE)
    public void delete(@RequestParam long id) {
        roleService.deleteById(id);
    }


    /**
     * 查询角色的权限列表(返回所有权限，标记是否有分配)
     */
    @RequestMapping("role/listPerm")
    public List<PermVO> listPerm(@RequestParam Long roleId) {
        //===1.取出所有权限模块
        Collection<AuthModuleBean> moduleBeans = LiveBeanPostProcessor.AUTHMODULE_MAP.values();
        //===2.查出角色的权限列表
        List<SysRolePerm> rolePerms = rolePermService.listRolePerm(roleId);
        Map<String, Integer> permMap = rolePerms.stream().collect(Collectors.toMap(e -> e.getAuthModuleCode() + "-" + e.getPermMethodCode(), e -> 1));
        //===3.设置权限是否分配给角色的标记
        List<PermVO> permList = Lists.newArrayList();
        for (AuthModuleBean moduleBean : moduleBeans) {
            PermVO vo = new PermVO();
            vo.setCode(moduleBean.getCode()).setDesc(moduleBean.getDesc());
            List<PermVO.PermMethod> permMethods = Lists.newArrayList();
            for (AuthMethod authMethod : AuthMethod.values()) {
                PermVO.PermMethod permMethod = new PermVO.PermMethod().setMethCode(authMethod.getCode()).setMethodDesc(authMethod.getDesc());
                if (permMap.containsKey(moduleBean.getCode() + "-" + authMethod.getCode())) {
                    permMethod.setAssigned(1);
                }
                permMethods.add(permMethod);
            }
            vo.setPermMethods(permMethods);

            permList.add(vo);
        }

        return permList;
    }

    /**
     * 全量更新角色权限
     */
    @RequestMapping("role/updatePerms/{roleId}")
    @SaCheckPermission(value = "role-update", orRole = "super-admin", type = SaTokenAdminUtil.TYPE)
    public void updatePerms(@PathVariable long roleId, @RequestBody List<SysRolePerm> rolePerms) {
        rolePermService.updatePerm(roleId, rolePerms);
    }


    /**
     * 给角色分配菜单
     */
    @RequestMapping("role/update-menu")
    @SaCheckPermission(value = "role-update", orRole = "super-admin", type = SaTokenAdminUtil.TYPE)
    public void updateMenu(@RequestParam Long roleId, @RequestParam String menuIds) {
        roleMenuService.updateMenu(roleId, menuIds);
    }

    /**
     * 查询用户的所有角色
     */
    @RequestMapping("role/listByUser")
    public List<SysRole> listByUser(@RequestParam Long userId) {
        return roleService.listByUser(userId);
    }
}
